package server.mapper;


import server.HttpServlet;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: zhouchao
 * @Date: 2021/06/20 13:38
 * @Description:
 */
public class Mapper {

    private List<MappedHost> hosts = new ArrayList<>();

    public List<MappedHost> getHosts() {
        return hosts;
    }

    public void setHosts(List<MappedHost> hosts) {
        this.hosts = hosts;
    }

    /**
     * 所有MapperHost的基类
     */
    protected abstract static class MapElement<T> {

        public final String name;
        public final T object;

        public MapElement(String name, T object) {
            this.name = name;
            this.object = object;
        }
    }

    /**
     * 封装MappedHost
     */
    public static final class MappedHost extends MapElement<Host> {
        public List<MappedContext> contextList;

        public MappedHost(String name, Host object) {
            super(name, object);
            contextList = new ArrayList<>();
        }

        public void addServlet(String url, HttpServlet httpServlet) {
            Wrapper wrapper = new Wrapper(httpServlet);
            MappedWrapper mappedWrapper = new MappedWrapper(url,wrapper);
            MappedContext mappedContext = new MappedContext(url,mappedWrapper);
            this.contextList.add(mappedContext);
        }
    }

    /**
     * 封装MappedContext
     */
    protected static final class MappedContext extends MapElement<Void> {
        public List<MappedWrapper> wrapperList;

        public MappedContext(String name, MappedWrapper object) {
            super(name, null);
            wrapperList = new ArrayList<>();
            this.wrapperList.add(object);
        }
    }

    /**
     * 封装MappedWrapper
     */
    protected static class MappedWrapper extends MapElement<Wrapper> {
        public MappedWrapper(String url, Wrapper wrapper) {
            super(url, wrapper);
        }
    }

    /**
     * 根据host和context匹配HttpServlet
     *
     * @param hostName
     * @param url
     * @return
     */
    public HttpServlet matchServlet(String hostName, String url) {
        int hostIndex = findIgnoreCase(hosts, hostName);
        if (hostIndex == -1) {
            return null;
        }
        MappedHost mappedHost = hosts.get(hostIndex);

        int contextNum = findIgnoreCase(mappedHost.contextList, url);
        if (contextNum == -1) {
            return null;
        }
        MappedContext mappedContext = mappedHost.contextList.get(contextNum);

        MappedWrapper mappedWrapper = mappedContext.wrapperList.get(0);

        return mappedWrapper.object.getInstance();
    }


    public static int findIgnoreCase(List<? extends MapElement> maps, String name) {
        for (int i = 0; i < maps.size(); i++) {
            MapElement<?> me = maps.get(i);
            if (me.name.equals(name)) {
                return i;
            }
        }
        return -1;
    }


}
